﻿
'Public Enum eFlags As UInt16
'    toClient = &H1US
'    toServer = &H2US
'    toClientCrypted = &H101US
'    toServerCrypted = &H102US

'    BlockedToClient = &H1001US
'    BlockedToServer = &H1002US
'    BlockedtoClientCrypted = &H1101US
'    BlockedtoServerCrypted = &H1102US

'    Block = &H10
'    UnBlock = &H20
'End Enum



Class cKtor
    Public LocalHostIP As String = "127.0.0.1"
    Public LiPortClient As UInt16 = 15779
    Public LiPortBot As UInt16 = 9000

    'Public LServerIp As String = "212.24.57.34" 'RSRO
    Public LServerIp As String = "121.128.133.28" 'ISRO
    Public LServerPort As UInt32 = 15779

    Public GServerIp As String
    Public GServerPort As UInt32

    Public ConnectToGS As Boolean = False

    Dim server As cConnectionBase
    Dim client As cConnectionBase
    Dim bot As cConnectionBase

    Dim ClientBlockList As New Collections.Generic.List(Of UInt16) 'Opcodes to block to client
    Dim ServerBlockList As New Collections.Generic.List(Of UInt16) 'Opcodes to block to server

    Dim pthPacketProcessor As Threading.Thread

    Sub New()
        server = New cSroTcpC 'cFakeServer("D:\VisualStudio_08\kbot, &Hsro\trunk\KTor\bin\x86\Debug\logs\PacketLog1.txt") 'cSroTcpC '
        client = New cSroTcpL
        bot = New cBotConnection
    End Sub

    'Sub New(ByVal ListenPort As UInt16, ByVal LoginServerIP As String, ByVal LoginServerPort As UInt16)
    '    LServerIp = LoginServerIP
    '    LServerPort = LoginServerPort
    '    LiPortClient = ListenPort

    '    server = New cSroTcpC
    '    client = New cSroTcpL
    'End Sub

    Public Function Start()
        client.Start(LocalHostIP, LiPortClient)
        bot.Start(LocalHostIP, 9000)

        pthPacketProcessor = New Threading.Thread(AddressOf PacketProcessor)
        pthPacketProcessor.IsBackground = True
        pthPacketProcessor.Start()
        Return 0
    End Function


    Sub PacketProcessor()
        Dim packet() As Byte
        Do

            'Check for client packet & handle it
            packet = client.Get_Packet
            If packet IsNot Nothing Then
                ClientPacketHandler(packet)
            Else
                If client.Status = cConnectionBase.eSocketStatus.Offline Then
                    server.Disconnect()
                    server.clear_buffer()
                    client.Start(LocalHostIP, LiPortClient)
                End If
            End If

            'Check for server packet & handle it
            packet = server.Get_Packet
            If packet IsNot Nothing Then
                ServerPacketHandler(packet)
            Else
                Threading.Thread.Sleep(2)
            End If

            'Check for bot packet & handle it
            packet = bot.Get_Packet
            If packet IsNot Nothing Then
                BotPacketHandler(packet)
            Else
                Threading.Thread.Sleep(2)
            End If
        Loop

    End Sub

    Sub ClientPacketHandler(ByRef packet As Byte())
        Dim opc As UInt16 = BitConverter.ToUInt16(packet, 2)
        If opc = &H9000 Then 'client is connected , &H, &H> start server connection and wait till connected
            If ConnectToGS = False Then
                server.Start(LServerIp, LServerPort)
            Else
                ConnectToGS = False
                server.Start(GServerIp, GServerPort)
            End If

            Do Until server.Status = cConnectionBase.eSocketStatus.Connected
                If server.Status = cConnectionBase.eSocketStatus.Offline Then
                    client.Disconnect()
                    server.clear_buffer()
                    client.clear_buffer()
                    client.Start(LocalHostIP, LiPortClient)
                    Exit Sub
                End If
                Threading.Thread.Sleep(50)
            Loop
        End If

        If ServerBlockList.Contains(opc) Then
            If bot.Status = cConnectionBase.eSocketStatus.Connected Then
                bot.Send(packet)
            End If
            packet(5) += &H10
        Else
            If bot.Status = cConnectionBase.eSocketStatus.Connected Then
                bot.Send(packet)
            End If
            server.Send(packet)
        End If


    End Sub
    Sub ServerPacketHandler(ByRef packet As Byte())
        'A102 L, &HG login Status
        '15, &H00, &H02, &HA1, &H01, &H01                      'header
        '01                                     'msgTyp 1, &H, &H> ok   2 , &H, &H> error
        '48, &H01, &H00, &H00                            'login id
        '0C, &H00                                  'IP len
        '32, &H31, &H32 2E 32, &H34 2E 35, &H37 2E 32, &H35    'IP
        '0B, &H3E                                  'Port 15883
        Dim opc As UInt16 = BitConverter.ToUInt16(packet, 2)

        Select Case opc
            Case &HA102US 'check if loginserver restrict us to gameserver 
                Dim r As New IO.BinaryReader(New IO.MemoryStream(packet))

                r.BaseStream.Position = 6
                If r.ReadByte = 1 Then

                    Dim w As New IO.BinaryWriter(r.BaseStream)


                    r.BaseStream.Position = 11
                    Dim len As UInt16 = r.ReadUInt16
                    GServerIp = Text.Encoding.ASCII.GetString(r.ReadBytes(len))
                    GServerPort = r.ReadUInt16
                    ConnectToGS = True


                    w.BaseStream.Position = 11 'header + flag + loginid
                    w.Write(CUShort(LocalHostIP.Length))
                    w.Write(Text.Encoding.ASCII.GetBytes(LocalHostIP))
                    w.Write(LiPortClient)
                    w.BaseStream.Position = 0
                    w.Write(CShort(1 + 4 + 2 + LocalHostIP.Length + 2))

                    w.Flush()

                    w.Close()
                    r.Close()

                    ReDim Preserve packet(6 + 1 + 4 + 2 + LocalHostIP.Length + 2 - 1)
                    client.Send(packet)

                    server.Disconnect()
                    Do Until client.Status = cConnectionBase.eSocketStatus.Offline
                    Loop
                    client.clear_buffer()
                    client.Start(LocalHostIP, LiPortClient)
                    Exit Sub
                End If

            Case &HA103 'check if gameserver accept the connection
                Using r As New IO.BinaryReader(New IO.MemoryStream(packet))
                    r.BaseStream.Position += 6
                    If r.ReadByte = 2 Then 'error 
                        Do Until server.Status = cConnectionBase.eSocketStatus.Offline
                            Threading.Thread.Sleep(50)
                        Loop
                        client.Send(packet)
                        Threading.Thread.Sleep(100)
                        client.Disconnect()
                        client.clear_buffer()
                        server.clear_buffer()
                        client.Start(LocalHostIP, LiPortClient)
                        Exit Sub
                    End If

                End Using
        End Select

        If ClientBlockList.Contains(opc) Then
            packet(5) += &H10
            If bot.Status = cConnectionBase.eSocketStatus.Connected Then
                bot.Send(packet)
            End If
        Else
            If bot.Status = cConnectionBase.eSocketStatus.Connected Then
                bot.Send(packet)
            End If
            client.Send(packet)
        End If




    End Sub
    Sub BotPacketHandler(ByRef packet As Byte())

        Dim flags As Byte = packet(4)

        Select Case flags
            Case &H1 'X1 = to client
                client.Send(packet)
            Case &H2 'X2 = to server
                server.Send(packet)
            Case &H11 '1X = block to client
                Dim opc As UInt16 = BitConverter.ToUInt16(packet, 2)
                If ClientBlockList.Contains(opc) = False Then
                    ServerBlockList.Add(opc)
                End If
            Case &H12 '1X = block to server
                Dim opc As UInt16 = BitConverter.ToUInt16(packet, 2)
                If ServerBlockList.Contains(opc) = False Then
                    ClientBlockList.Add(opc)
                End If
            Case &H21 '2X = unblock to client
                Dim opc As UInt16 = BitConverter.ToUInt16(packet, 2)
                If ClientBlockList.Contains(opc) = True Then
                    ServerBlockList.Remove(opc)
                End If
            Case &H22 '2X = unblock to server
                Dim opc As UInt16 = BitConverter.ToUInt16(packet, 2)
                If ServerBlockList.Contains(opc) = True Then
                    ClientBlockList.Remove(opc)
                End If
        End Select

    End Sub
End Class
